﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ModifyMimeTypes
{
    public partial class ModifyMimeTypes : Form
    {
        MimeHelper mh; //Class used to get mime types from AD
        BindingList<string> mimeTypeList; //This is the list of mime types that will go in our list box
        bool mouseDown = false; //Keeps track of whether the mouse is down for Move Up/Move Down

        public ModifyMimeTypes()
        {
            InitializeComponent();
        }

        //Updates the list box with a new version of the mimeTypeList
        public void UpdateMimeTypeList()
        {
            listMimeTypes.DataSource = mimeTypeList;
        }

        //Used to move the selected item one position down in the list
        private void MoveItemDownInList()
        {
            int index = listMimeTypes.SelectedIndex;

            if (index != mimeTypeList.Count - 1)
            {
                string type = mimeTypeList[index];
                mimeTypeList.RemoveAt(index);
                mimeTypeList.Insert(index + 1, type);

                listMimeTypes.DataSource = null;
                listMimeTypes.DataSource = mimeTypeList;
                listMimeTypes.SelectedIndex = index + 1;
            }
        }

        //Used to move the selected item one position up in the list
        private void MoveItemUpInList()
        {
            int index = listMimeTypes.SelectedIndex;

            if (index != 0)
            {
                string type = mimeTypeList[index];
                mimeTypeList.RemoveAt(index);
                mimeTypeList.Insert(index - 1, type);

                listMimeTypes.DataSource = null;
                listMimeTypes.DataSource = mimeTypeList;
                listMimeTypes.SelectedIndex = index - 1;
            }
        }

        //Handles the work of the Move Up/Down buttons i.e. moving the
        //selected item up or down in the list.
        private void DoButtonDownWork(string senderName)
        {
            mouseDown = true; //Mark that the mouse is currently down

            while (mouseDown)
            {
                Application.DoEvents(); //Give the MouseUp event a chance to occur

                if (!mouseDown)
                {
                    break;
                }

                int index = listMimeTypes.SelectedIndex;

                switch (senderName)
                {
                    case "btnDown":
                        MoveItemDownInList();

                        break;
                    case "btnUp":
                        MoveItemUpInList();

                        break;
                }

                Application.DoEvents();

                System.Threading.Thread.Sleep(50); //Give the MouseUp event a chance to occur
            }
        }

        //Called on Form load. Loads up Mime Types from AD
        private void Form_Load(object sender, EventArgs e)
        {
            this.btnReloadMimeTypes.PerformClick();
        }

        //Handles clicking of all buttons in the form
        private void btnClick(object sender, EventArgs e)
        {
            string buttonName = ((Button)sender).Name;

            switch (buttonName)
            {
                case "btnReloadMimeTypes":
                    {
                        try
                        {
                            mh = new MimeHelper();
                            mimeTypeList = mh.GetMimeTypes();

                            UpdateMimeTypeList();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Unable to get mime type list from Active Directory with error: " + ex.Message, "Error");
                            this.Close(); //Close the form
                        }
                    }

                    break;

                case "btnSave":
                    {
                        try
                        {
                            mh.SaveMimeTypes(mimeTypeList);

                            MessageBox.Show("Successfully saved mime types to Active Directory", "Success");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Unable to save changes with error: " + ex.Message, "Error");
                        }
                    }

                    break;

                case "btnEdit":
                case "btnNew":
                    {
                        EditTypeForm etf = new EditTypeForm(buttonName == "btnEdit" ? mimeTypeList[listMimeTypes.SelectedIndex] : "");

                        etf.ShowDialog();

                        string type = etf.MimeType.ToLower();

                        //Check for duplicate entries
                        if (!mimeTypeList.Contains(type))
                        {
                            //Check if the MimeType was modified and validated. If so, update the list
                            if (type != "")
                            {
                                if (buttonName == "btnEdit")
                                {
                                    mimeTypeList[listMimeTypes.SelectedIndex] = type;
                                }
                                else
                                {
                                    mimeTypeList.Add(type); //Add entry to the end of the list
                                    listMimeTypes.SelectedIndex = mimeTypeList.Count - 1; //Move the listbox index to the end of the list
                                }
                            }
                        }
                        else
                        {
                            MessageBox.Show("The specified type already exists", "Error");
                        }
                    }
                    break;

                case "btnDelete":
                    {
                        int index = listMimeTypes.SelectedIndex;
                        mimeTypeList.RemoveAt(index);
                    }

                    break;

                case "btnCopyList":
                    {
                        string types = "";

                        for (int i = 0; i < mimeTypeList.Count; i++)
                        {
                            types += mimeTypeList[i] + "\r\n";
                        }

                        Clipboard.SetText(types);
                    }

                    break;

                case "btnTop":
                    {
                        int index = listMimeTypes.SelectedIndex;
                        string type = mimeTypeList[index];
                        mimeTypeList.RemoveAt(index);
                        mimeTypeList.Insert(0, type);
                        listMimeTypes.SelectedIndex = 0;
                    }

                    break;

                case "btnBottom":
                    {
                        int index = listMimeTypes.SelectedIndex;
                        string type = mimeTypeList[index];
                        mimeTypeList.RemoveAt(index);
                        mimeTypeList.Add(type);
                        listMimeTypes.SelectedIndex = mimeTypeList.Count - 1;
                    }

                    break;
            }
        }

        //MouseUp event handler for the Move Up and Move Down buttons.
        //Sets the mouseDown boolean to false
        private new void MouseUp(object sender, MouseEventArgs e)
        {
            mouseDown = false;
        }

        //KeyUp event handler for the Move Up and Move Down buttons.
        //Sets the mouseDown boolean to false
        private new void KeyUp(object sender, KeyEventArgs e)
        {
            mouseDown = false;
        }

        //MouseDown event handler for the Move Up and Move Down buttons.
        //Used so the buttons can be held to make multiple moves at a time
        private new void MouseDown(object sender, MouseEventArgs e)
        {
            DoButtonDownWork(((Button)sender).Name);
        }

        //KeyDown event handler for all buttons.
        //For the Move Up/Down buttons, used so the buttons can be held to make 
        //multiple moves at a time. For the rest of the buttons just clicks the button.
        //Only accepts the Enter or Space key to press the button. 
        private new void KeyDown(object sender, KeyEventArgs e)
        {
            Button b = (Button)sender;

            if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return || e.KeyCode == Keys.Space)
            {
                if (b.Name == "btnUp" || b.Name == "btnDown")
                {
                    DoButtonDownWork(((Button)sender).Name);
                }
                else
                {
                    b.PerformClick();
                }
            }
        }

        //By default, the Enter key is intercepted before it makes it to the KeyDown event.
        //This means if the user highlights the Move Up/Down buttons and holds enter
        //the buttons will not get clicked (which means we can't do the same thing
        //we do for MouseUp/Down). Here we override processing of the Enter key so it
        //will make it to KeyDown.
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData != Keys.Enter)
            {
                return base.ProcessDialogKey(keyData);
            }
            else
            {
                return false;
            }
        }
    }
}
